﻿using UnityEngine;
using Gamekit2D;

public class Beat : MonoBehaviour
{
    private Vector3 SpawnPosition;
    private Vector3 TargetPosition;
    private float beforeTriggerDuration;
    private float lerpTime;
    private bool bCanMove = false;
    private float moveStartTime = 0;
    private float lifeSpanTime = 0;
    public float noFailureTriggerTime_MS = 100;
    public float validTriggerTime_MS = 100;
    Timer autoDestroyTimer = null;
    Timer validCheckTimer = null;
    bool isAutoTrigger = false;
    bool isTriggered = false;
    GameObject TriggerFXGo = null;

    private void Start() 
    {
        if (LoadingPanel._sceneToLoad == "GameScene_1")
        {
            TriggerFXGo = Resources.Load<GameObject>(Global.SONG_TRIGGER_FX_BASE_PATH + "1");
        }
        if (LoadingPanel._sceneToLoad == "GameScene_2")
        {
            TriggerFXGo = Resources.Load<GameObject>(Global.SONG_TRIGGER_FX_BASE_PATH + "2");
        }
        if (LoadingPanel._sceneToLoad == "GameScene_3")
        {
            TriggerFXGo = Resources.Load<GameObject>(Global.SONG_TRIGGER_FX_BASE_PATH + "3");
        }
        if (LoadingPanel._sceneToLoad == "GameScene_4")
        {
           TriggerFXGo = Resources.Load<GameObject>(Global.SONG_TRIGGER_FX_BASE_PATH + "4");
        }
    }
    private void FixedUpdate() {
        TickLocation();
    }

    private void TickLocation()
    {
        if (bCanMove)
        {
            lerpTime += 1.0f / beforeTriggerDuration * Time.fixedDeltaTime;
            transform.position = Vector3.Lerp(SpawnPosition, TargetPosition, lerpTime);
        }
    }
    public void Init(Vector3 newSpawnPosition, Vector3 newTargetPosition, float newBeforeTriggerDuration, bool bIsAutoTrigger, KeyCode correctKey)
    {
        SpawnPosition = newSpawnPosition;
        TargetPosition = newTargetPosition;
        beforeTriggerDuration = newBeforeTriggerDuration;
        moveStartTime = Time.time;
        bCanMove = true;
        lifeSpanTime = newBeforeTriggerDuration + 1;
        isAutoTrigger = bIsAutoTrigger;
        autoDestroyTimer = Timer.Register(lifeSpanTime, Recycle,
        (float tickTime) =>
        {
            if (Input.GetKeyDown(correctKey))
            {
                IputTriggerBeat();
            }
        });
        validCheckTimer = Timer.Register(beforeTriggerDuration + noFailureTriggerTime_MS / 1000.0f, CheckTrigger);
    }

    public void IputTriggerBeat()
    {
        float triggerTime = Time.time;
        float triggerDeltaTime = triggerTime - moveStartTime - beforeTriggerDuration;
        bool bIsValidInput = Mathf.Abs(triggerDeltaTime) <= validTriggerTime_MS / 1000.0f;
        bool bIsSuccess = Mathf.Abs(triggerDeltaTime) <= noFailureTriggerTime_MS / 1000.0f;

        if (bIsValidInput && !isAutoTrigger && !isTriggered)
        {
            if (bIsSuccess)
            {
                PlayerDoTrigger();
            }
            else
            {
                DoFailure();
            }
        }
    }

    void CheckTrigger()
    {
        if (!isTriggered)
        {
            if (isAutoTrigger)
            {
                DoTrigger();
            }
            else
            {
                DoFailure();
            }
        }
    }

    void DoTrigger()
    {
        // Debug.Log(gameObject.name + " DoTrigger");
        isTriggered = true;
        if(TriggerFXGo)
        {
            GameObject TriggerFX = GameObject.Instantiate(TriggerFXGo);
            TriggerFX.transform.position = TargetPosition;
            Timer.Register(1, ()=>{GameObject.Destroy(TriggerFX);});
        }
        ImmediatelyFadeOutStep();
    }

    void PlayerDoTrigger()
    {
        DoTrigger();
        UIControl.instance.playState(true);
    }

    void ImmediatelyFadeOutStep()
    {
        Vector3 fadeOutSrcScale = transform.localScale;
        Vector3 fadeOutRetScale = 0.8f * fadeOutSrcScale;
        SpriteRenderer spriteComp = transform.GetComponent<SpriteRenderer>();
        Color fadeOutSrcColor = spriteComp.color;
        Color fadeOutRetColor = 0.5f * fadeOutSrcColor;

        float fadeOutTime = 0;
        Timer.Register(0.2f, () => { Recycle(); },
        (float tickTime) =>
        {
            fadeOutTime += tickTime * 0.2f;
            transform.localScale = Vector3.Lerp(fadeOutSrcScale, fadeOutRetScale, fadeOutTime);
            spriteComp.color = Color.Lerp(fadeOutSrcColor, fadeOutRetColor, fadeOutTime);
        });
    }

    void DoFailure()
    {
        //Debug.Log(gameObject.name + " Failure");
        isTriggered = true;
        ImmediatelyFadeOutStep();
        UIControl.instance.playState(false);
    }

    void Recycle()
    {
        Timer.Cancel(autoDestroyTimer);
        Destroy(gameObject);
    }
    private void OnDestroy()
    {

    }
}
